﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Net.Mail;
using System.Web.UI.WebControls;
using DataModel;
using ExtensionMethods;

namespace FriendsContactWeb
{
    public partial class _Default : System.Web.UI.Page
    {
        const int MSG_ID_COL_NO = 0;
        const int EVENT_ID_COL_NO = 1;
        const int USER_ID_COL_NO = 2;

        DataClass dataClass = null;
        List<FriendsEvent> currentMonthEvents = null;
        List<FriendsEvent> currentDayEvents = null;

        protected void Page_Load(object sender, EventArgs e)
        {
            try
            {
                if (!IsPostBack)
                {
                    dataClass = new DataClass(Page.User.Identity.Name);
                    Session["dataClass"] = dataClass;

                    this.eventCalendar.SelectedDate = DateTime.Today;
                    currentMonthEvents = dataClass.GetEventsForDate(this.eventCalendar.SelectedDate);
                    Session["currentMonthEvents"] = currentMonthEvents;
                }
            }
            catch (Exception ex)
            {
                ProcessException(ex);
            }
        }
                
        #region EventCalendar events
        
        protected void eventCalendar_VisibleMonthChanged(object sender, MonthChangedEventArgs e)
        {
            try
            {
                dataClass = (DataClass)Session["dataClass"];
                currentMonthEvents = dataClass.GetEventsForDate(e.NewDate);
                Session["currentMonthEvents"] = currentMonthEvents;
                this.eventDataPanel.Visible = false;
            }
            catch (Exception ex)
            {
                ProcessException(ex);
            }
        }

        protected void eventCalendar_DayRender(object sender, DayRenderEventArgs e)
        {
            if (currentMonthEvents == null)
                currentMonthEvents = (List<FriendsEvent>)Session["currentMonthEvents"];

            if (currentMonthEvents.IsDateInEventList(e.Day.Date))
            {
                e.Cell.BackColor = System.Drawing.Color.FromArgb(10, 36, 106);
            }

            if (e.Day.Date.Equals(DateTime.Today.Date))
            {
                eventCalendar_SelectionChanged(sender, null);
            }
        }

        protected void eventCalendar_SelectionChanged(object sender, EventArgs e)
        {
            dataClass = (DataClass)Session["dataClass"];
            if (currentMonthEvents == null)
                currentMonthEvents = (List<FriendsEvent>)Session["currentMonthEvents"];

            if (currentDayEvents == null)
                currentDayEvents = dataClass.GetEventsForDay(this.eventCalendar.SelectedDate,
                                                             Page.User.Identity.Name);

            if (Session["AddNewEvent"] != null)
            {
                if ((DateTime)Session["AddNewEvent"] == this.eventCalendar.SelectedDate)
                {
                    FillEventsFromDaySelecting();
                    return;
                }
            }

            if (currentDayEvents.Count == 0)
            {
                ClearEventControls();
                this.eventDataPanel.Visible = false;
                this.btnDelete.Visible = false;
                Session["CurrentDay"] = this.eventCalendar.SelectedDate;
                return;
            }
            else if (currentDayEvents.Count > 0)
            {
                if (IsSelectedDayChanged())
                {
                    FillEventsFromDaySelecting();
                }
                else
                {
                    FillEventDataFromDropDownList();
                }

                ManageFeedback();
            }
            else
            {
                ClearEventControls();
                this.eventDataPanel.Visible = false;
            }

            Session["CurrentDay"] = this.eventCalendar.SelectedDate;
        }
                                
        #endregion EventCalendar events

        #region Controls events

        protected void btnAdd_Click(object sender, EventArgs e)
        {
            try
            {
                Session["AddNewEvent"] = eventCalendar.SelectedDate;
                eventCalendar_SelectionChanged(sender, e);
            }
            catch (Exception ex)
            {
                ProcessException(ex);
            }
        }

        protected void btnDelete_Click(object sender, EventArgs e)
        {
            decimal eventId = 0;
            string title = String.Empty;
            DateTime tempDate = this.eventCalendar.SelectedDate;
            dataClass = (DataClass)Session["dataClass"];

            try
            {
                title = this.titleTextBox.Text;

                if (currentDayEvents == null)
                    currentDayEvents = dataClass.GetEventsForDay(this.eventCalendar.SelectedDate,
                                                                 Page.User.Identity.Name);

                eventId = currentDayEvents.Where(t => t.Title == title).FirstOrDefault().Id;
                currentMonthEvents = dataClass.GetEventsForDate(this.eventCalendar.SelectedDate);

                if (eventId > 0)
                {
                    dataClass.DeleteEvent(eventId);
                    currentMonthEvents = currentMonthEvents.RemoveEventById(eventId);
                    currentDayEvents = currentDayEvents.RemoveEventById(eventId);
                    
                    Session["currentMonthEvents"] = currentMonthEvents;

                    this.eventTitleList.Items.Remove(new ListItem(title, eventId.ToString()));
                    this.eventCalendar_SelectionChanged(sender, e);
                }
            }
            catch (Exception ex)
            {
                ProcessException(ex);
            }
        }

        protected void btnSave_Click(object sender, EventArgs e)
        {
            decimal eventId = 0;
            DateTime eventDate = DateTime.MinValue;
            string title = String.Empty;
            string author = String.Empty;
            string note = String.Empty;
            dataClass = (DataClass)Session["dataClass"];

            try
            {
                eventDate = this.eventCalendar.SelectedDate;
                title = this.titleTextBox.Text;
                author = this.authorTextBox.Text;
                note = this.eventDescTextBox.Text;
                
                if (currentDayEvents == null)
                    currentDayEvents = dataClass.GetEventsForDay(this.eventCalendar.SelectedDate, 
                                                                 Page.User.Identity.Name);

                if (eventTitleList.Items.Count > 0)
                {
                    var eventIdTemp = currentDayEvents.Where(w => w.Title == title)
                                                      .FirstOrDefault();
                    
                    if (eventIdTemp != null)
                    {
                        eventId = eventIdTemp.Id;
                        dataClass.SaveChangesForEvent(eventId, eventDate, author, title, note);
                    }
                }
                else
                {
                    decimal tempNewEventId = dataClass.AddNewEvent(eventDate, author, title, note);
                    this.currentDayEvents = dataClass.GetEventsForDay(this.eventCalendar.SelectedDate,
                                                                      Page.User.Identity.Name);
                    Session["AddNewEvent"] = null;
                    currentMonthEvents = dataClass.GetEventsForDate(eventDate);
                    Session["currentMonthEvents"] = currentMonthEvents;

                    this.eventTitleList.Items.Add(new ListItem(title, tempNewEventId.ToString()));
                }
                FillEventsFromDaySelecting();
                this.eventCalendar_SelectionChanged(sender, e);
            }
            catch(Exception ex)
            {
                ProcessException(ex);
            }
        }

        protected void btnSendToOthers_Click(object sender, EventArgs e)
        {
            decimal eventId = 0;
            DateTime eventDate = DateTime.MinValue;
            string title = String.Empty;
            string author = String.Empty;
            dataClass = (DataClass)Session["dataClass"];

            try
            {
                eventDate = this.eventCalendar.SelectedDate.Equals(DateTime.MinValue) ?
                                 DateTime.Today : this.eventCalendar.SelectedDate;
                title = this.titleTextBox.Text;
                author = this.authorTextBox.Text;

                if (currentDayEvents == null)
                    currentDayEvents = dataClass.GetEventsForDay(eventDate, Page.User.Identity.Name);

                if (eventTitleList.Items.Count > 0)
                {
                    eventId = currentDayEvents.Where(w => w.Title == title)
                                                      .FirstOrDefault().Id;

                    dataClass.SendMessageToOtherUsers(eventId, author);
                }
            }
            catch (Exception ex)
            {
                ProcessException(ex);
            }
        }
                
        protected void feedbackGridView_RowDataBound(object sender, GridViewRowEventArgs e)
        {
            try
            {
                e.Row.Cells[MSG_ID_COL_NO].Visible = false;
                e.Row.Cells[EVENT_ID_COL_NO].Visible = false;
                e.Row.Cells[USER_ID_COL_NO].Visible = false;
            }
            catch (Exception ex)
            {
                ex.ToString();
            }
        }

        protected void eventTitleList_SelectedIndexChanged(object sender, EventArgs e)
        {
            FillEventDataFromDropDownList();
        }

        #endregion Controls events

        #region Supported methods

        private void ManageFeedback()
        {
            decimal eventId = 0;
            DateTime eventDate = DateTime.MinValue;
            string title = String.Empty;
            string author = String.Empty;
            dataClass = (DataClass)Session["dataClass"];
            List<UserEventsFeedback> feedbackList = null;

            try
            {
                eventDate = this.eventCalendar.SelectedDate.Equals(DateTime.MinValue) ?
                                 DateTime.Today : this.eventCalendar.SelectedDate;
                title = this.titleTextBox.Text;
                author = this.authorTextBox.Text;

                if (currentDayEvents == null)
                    currentDayEvents = dataClass.GetEventsForDay(eventDate, Page.User.Identity.Name);

                if (eventTitleList.Items.Count == 0)
                {
                    this.feedbackPanel.Visible = false;
                    return;
                }
                else
                {
                    eventId = currentDayEvents.Where(w => w.Title == title)
                                                      .FirstOrDefault().Id;

                    feedbackList = dataClass.GetFeedbackForEvent(eventId);
                    if (feedbackList.Count > 0)
                    {
                        this.feedbackPanel.Visible = true;
                        this.feedbackGridView.DataSource = feedbackList;
                        this.feedbackGridView.DataBind();
                    }
                    else
                        this.feedbackPanel.Visible = false;
                }
            }
            catch (Exception ex)
            {
                ProcessException(ex);
            }
        }

        private void ClearEventControls()
        {
            try
            {
                this.eventTitleList.Items.Clear();
                this.titleTextBox.Text = String.Empty;
                this.authorTextBox.Text = Page.User.Identity.Name;
                this.eventDescTextBox.Text = String.Empty;
            }
            catch (Exception ex)
            {
                ProcessException(ex);
            }
        }

        private void ProcessException(Exception ex)
        {
            if (Request.IsLocal)
            {
                string exMessage = "General info: " + ex.Message;
                
                if (ex.InnerException != null)
                    exMessage += "\nInner Message: " + ex.InnerException.Message;

                exMessage += "\n\nStackTrace:\n" + ex.StackTrace;
                Session["CurrentError"] = exMessage;
            }
            else
            {
                Session["CurrentError"] = "Error processing page.";
            }
            Server.Transfer("ErrorPage.aspx");
        }

        private void ClearSesssionDate()
        {
            if (Session["AddNewEvent"] == null)
                return;

            DateTime calendarDate = this.eventCalendar.SelectedDate;
            DateTime sessionDate = (DateTime)Session["AddNewEvent"];
            if (!calendarDate.Equals(sessionDate))
            {
                Session["AddNewEvent"] = null;
            }
        }

        private void FillEventDataFromDropDownList()
        {
            try
            {
                if (this.eventTitleList.SelectedItem == null)
                    return;

                dataClass = (DataClass)Session["dataClass"];
                string selectedTitle = this.eventTitleList.SelectedItem.Text;
                FriendsEvent item = null;
                decimal selectedEventId = 
                    Convert.ToDecimal(this.eventTitleList.Items.FindByText(selectedTitle).Value);

                item = dataClass.GetEventFromId(selectedEventId);

                this.titleTextBox.Text = selectedTitle;
                this.authorTextBox.Text = GetUserNameFromParent(item);
                
                if (currentDayEvents == null)
                    currentDayEvents = dataClass.GetEventsForDay(this.eventCalendar.SelectedDate, 
                                                                 Page.User.Identity.Name);

                this.eventDescTextBox.Text =
                    currentDayEvents.Where(f => f.Id == selectedEventId).FirstOrDefault().Note;

                this.btnSave.Enabled = 
                    this.btnSendToOthers.Enabled = 
                    this.authorTextBox.Text.Equals(Page.User.Identity.Name);
            }
            catch (Exception ex)
            {
                ProcessException(ex);
            }
        }

        private void FillEventsFromDaySelecting()
        {
            dataClass = (DataClass)Session["dataClass"];
            if (currentMonthEvents == null)
            {
                currentMonthEvents = dataClass.GetEventsForDate(this.eventCalendar.SelectedDate);
            }

            if (Session["AddNewEvent"] != null && 
                (DateTime)Session["AddNewEvent"] == this.eventCalendar.SelectedDate)
            {
                this.eventDataPanel.Visible = true;
                this.btnDelete.Visible = true;
                ClearEventControls();
                return;
            }

            if (currentMonthEvents.IsDateInEventList(this.eventCalendar.SelectedDate) ||
                (currentMonthEvents.IsDateInEventList(DateTime.Today.Date) && this.eventCalendar.SelectedDate.Equals(DateTime.MinValue))
                )
            {
                this.eventDataPanel.Visible = true;
                this.btnDelete.Visible = true;
                ClearEventControls();

                try
                {
                    if (this.eventCalendar.SelectedDate.Equals(DateTime.MinValue))
                        currentDayEvents = dataClass.GetEventsForDay(DateTime.Today.Date, Page.User.Identity.Name);
                    else
                        currentDayEvents = dataClass.GetEventsForDay(this.eventCalendar.SelectedDate, Page.User.Identity.Name);

                    if (currentDayEvents != null && currentDayEvents.Count > 0)
                    {
                        foreach (FriendsEvent item in 
                            currentDayEvents.AsEnumerable().OrderBy(d => d.EventDate))
                        {
                            this.eventTitleList.Items.Add(new ListItem(item.Title, item.Id.ToString()));
                        }

                        foreach (FriendsEvent item in 
                            currentDayEvents.AsEnumerable().OrderBy(d => d.EventDate))
                        {
                            this.titleTextBox.Text = item.Title;
                            this.authorTextBox.Text = GetUserNameFromParent(item);
                            this.eventDescTextBox.Text = item.Note;
                            string temp = this.eventTitleList.SelectedItem.Text;
                            break;
                        }

                        this.btnSave.Enabled = 
                            this.btnSendToOthers.Enabled = 
                            this.authorTextBox.Text.Equals(Page.User.Identity.Name);
                    }
                }
                catch (Exception ex)
                {
                    ProcessException(ex);
                }
            }
            else
            {
                ClearEventControls();
                this.eventDataPanel.Visible = false;
                this.btnDelete.Visible = false;
            }

            ClearSesssionDate();
        }

        private string GetUserNameFromParent(FriendsEvent item)
        {
            if (item == null) 
                return String.Empty;

            dataClass = (DataClass)Session["dataClass"];
            string returnedUserName = String.Empty;

            if (item.Id_UserParent != Guid.Empty)
            {
                returnedUserName = dataClass.GetUserNameFromEvent(item);
            }
            else
            {
                returnedUserName = item.UserName;    
            }
            return returnedUserName;
        }

        private bool IsSelectedDayChanged()
        {
            if (Session["CurrentDay"] == null)
            {
                return true;
            }
            if (((DateTime)Session["CurrentDay"]).Equals(this.eventCalendar.SelectedDate))
            {
                return false;
            }
            else
            {
                Session["CurrentDay"] = this.eventCalendar.SelectedDate;
                return true;
            }
        }

        #endregion Supported methods

        
                              
    }
}
